package edu.uc.persistence;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.preference.PreferenceManager;
import android.util.Log;

import edu.uc.dto.User;
import edu.uc.ui.MainActivity;

/**
 * Creates the general user functions.
 * 
 * >> save (stores gather variables as a user object in local database table USERS)
 * >> fetch (searches database table USERS for User object with matching EMAIL)
 * >> fetchAllUsers (pulls all users from database into a hashmap)
 * >> logon (checks User object against database USERS and sets SessionUser global values)
 * 
 * @author Robert
 *
 */
public class UserDAO extends SQLiteOpenHelper implements UserDAOInterface {

	// Define String Variables
	private static final String SQL_ID = "_id";
	private static final String USERS = "users";
	private static final String FIRST_NAME = "firstName";
	private static final String LAST_NAME = "lastName";
	private static final String EMAIL = "email";
	private static final String PASSWORD = "password";
	
	// Define DB Variables
	private static final int DATABASE_VERSION = 1;
	private static final String DATABASE_NAME = "foodview";
	private final String CLASS_NAME = getClass().getName();
	
	// Declare new object
	UserDAO testNew;
	
	// Create Context
	public UserDAO(Context context) {
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		
		// CREATE TABLE statement
		String createUserDB = "CREATE TABLE "+USERS+" ("+SQL_ID+" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +FIRST_NAME+ " TEXT NOT NULL, "+LAST_NAME+" TEXT NOT NULL, "+EMAIL+" TEXT NOT NULL, "+PASSWORD+" TEXT NOT NULL);";
		Log.d(CLASS_NAME, createUserDB);
		
		// Execute statement
		db.execSQL(createUserDB);
	}
	
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub

	}
	
	@Override
	public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
	}
	
	@Override
	public List<User> fetchAllUsers() throws Exception {
		
		// Create the return hash
		List<User> allUsers = new ArrayList<User>();
		
		// SQL statement
		String selectSQL = "SELECT * FROM " + USERS ;
		
		Log.d(CLASS_NAME, selectSQL);
		
		// Create the result set
		Cursor cursor = getReadableDatabase().rawQuery(selectSQL, null);
		
		// Iterate over the results
		if (cursor.getCount() > 0) {
			Log.i(CLASS_NAME, cursor.getCount() + " results returned");
			
			// Move the cursor to the very first result.
			cursor.moveToFirst();
			
			// Iterate over our results.  Keep iterating as long as we're not after the last row.
			while(!cursor.isAfterLast()) {

				// Define user object
				User thisUser = new User();
				
				// Fill the user table with current user
				thisUser.setSqlId(cursor.getLong(0));
				thisUser.setFirstName(cursor.getString(1));
				thisUser.setLastName(cursor.getString(2));
				thisUser.setEmail(cursor.getString(3));
				thisUser.setPassword(cursor.getString(4));
				
				// Add the user
				allUsers.add(thisUser);
				
				// Log the user
				Log.d(CLASS_NAME, thisUser.toString());
				
				// Continue the loop
				cursor.moveToNext();
				
			}
			// Close the process at the end
			cursor.close();
			
		} else {
			Log.i(CLASS_NAME, "No results returned");			
		}
		
		return allUsers;
	}
	
	@Override
	public void save(User user) throws Exception {

		try {

			// Create a ContentValues, which is like a HashMap for data that we want to store in the database.
			ContentValues values = new ContentValues();
			values.put(SQL_ID, user.getUserId());
			values.put(FIRST_NAME, user.getFirstName());
			values.put(LAST_NAME, user.getLastName());
			values.put(EMAIL, user.getEmail());
			values.put(PASSWORD, user.getPassword());

			// Store Variables into the Database
			long sqlId = getWritableDatabase().insert(USERS, null, values);

			// Update the User with SQL ID.
			user.setSqlId(sqlId);

		} catch (Exception e) {
			Log.e(getClass().getName(), "Error saving new user: " + e.getMessage());
			e.printStackTrace();
		}
	}
	
	@Override
	public User fetchUser(String Email) throws Exception {
		
		// create a return value.
		User FetchedUser = new User();
		
		// the SQL to retrieve plants from our database.
		String selectSQL = "SELECT * FROM " + USERS + " WHERE " + EMAIL + "='" + Email + "'";
		
		Log.d(CLASS_NAME, selectSQL);
		
		// get a cursor, which is like a ResultSet.  It allows us to iterate over results.
		Cursor cursor = getReadableDatabase().rawQuery(selectSQL, null);
		
		// iterate over results.
		if (cursor.getCount() > 0) {
			Log.i(CLASS_NAME, cursor.getCount() + " results returned");
			// move the cursor to the very first result.
			cursor.moveToFirst();
			
			// populate
			FetchedUser.setUserId(cursor.getString(0));
			FetchedUser.setFirstName(cursor.getString(1));
			FetchedUser.setLastName(cursor.getString(2));
			FetchedUser.setEmail(cursor.getString(3));
			FetchedUser.setPassword(cursor.getString(4));
				
			// close the cursor.
			cursor.close();
			
		} else {
			Log.i(CLASS_NAME, "No results returned");			
		}
		
		return FetchedUser;
	}
	

	@Override
	public User logon(String Email, String Password) throws Exception {
		
		// TODO Auto-generated method stub
		
		// Fetch User
		User SessionUser = fetchUser(Email);
		
		Log.d(CLASS_NAME, "User FirstName from Hashmap: " + SessionUser.getFirstName());
		Log.d(CLASS_NAME, "User LastName from Hashmap: " + SessionUser.getLastName());
		Log.d(CLASS_NAME, "User ID from Hashmap: " + SessionUser.getUserId());
		Log.d(CLASS_NAME, "User Email from Hashmap: " + SessionUser.getEmail());
		Log.d(CLASS_NAME, "Password from Hashmap: " + SessionUser.getPassword());
		Log.d(CLASS_NAME, "Password from user input: " + Password);


		if(Password.equals(SessionUser.getPassword())) {
			Log.d(CLASS_NAME, "USER CONFIRMED");

			// Reference SessionUserMgr shared preference from context of MainActivity
			SharedPreferences SessionUserMgr = PreferenceManager.getDefaultSharedPreferences(MainActivity.context);

			// Set Global List to reflect current SessionUser object
			SharedPreferences.Editor edit = (SessionUserMgr).edit();
			edit.putString("User_Id", SessionUser.getUserId());
			edit.putString("First_Name", SessionUser.getFirstName());
			edit.putString("Last_Name", SessionUser.getLastName());
			edit.putString("Email", SessionUser.getEmail());
			edit.putString("Password", SessionUser.getPassword());
			edit.commit();

			// Return the final user values
			return SessionUser;
		}

		else {
			Log.d(CLASS_NAME, "INVALID PASSWORD");
			throw new IOException("Invalid Password was entered!");
		}
	}
}